#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>

int map[4][4];
int movenum = 0;
char input;
int gameover = 1;
int change = 1;

void menu()
{
    system("CLS");
    printf("         welcome to 2048\n");
    printf("---------------------------------------\n");
    printf("    W--up  S--down A--left D--right\n");
    printf("plese enter 0 if you do not want to play\n");
    printf("move: %d\n", movenum);
    printf("---------------------------------------\n");

    int i = 0;
    for (i = 0; i <= 3; i++)
    {
        int j = 0;
        for (j = 0; j <= 3; j++)
        {
            printf("   ");
            if (map[i][j] == 0) printf("|     ");
            else printf("|%5d", map[i][j]);
        }
        printf("\n|---------------------------------------|\n");
    }

}

int randnum()
{
    int i, j, n;
    if (change >= 1)
    {
        do
        {
            i = ((unsigned)rand()) % 4;
            j = ((unsigned)rand()) % 4;
        } while (map[i][j] != 0);
        n = ((unsigned)rand()) % 2;
        if (n == 0) map[i][j] = n + 2;
        else map[i][j] = n + 3;
        movenum++;
    }
}

int up()
{
    int now, next, k;
    for (int j = 0; j <= 3; j++)
    {
        for (int i = 0; i <= 3; i++)
        {
            now = map[i][j];
            if (now != 0)
            {
                k = i + 1;
                while (k < 4)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        if (now == next)
                        {
                            change = 1;
                            map[i][j] = 2 * map[k][j];
                            map[k][j] = 0;
                        }
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }

    for (int j = 0; j <= 3; j++)
    {
        for (int i = 0; i <= 3; i++)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = 1 + i;
                while (k < 4)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = next;
                        map[k][j] = 0;
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }
    return change;
}


int left()
{
    int now, next, k;
    for (int i = 0; i <= 3; i++)
    {
        for (int j = 0; j <= 3; j++)
        {
            now = map[i][j];
            if (now != 0)
            {
                k = j + 1;
                while (k < 4)
                {
                    next = map[i][k];
                    if (next != 0)
                    {
                        if (now == next)
                        {
                            change = 1;
                            map[i][j] = 2 * map[i][k];
                            map[i][k] = 0;
                        }
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }

    for (int j = 0; j <= 3; j++)
    {
        for (int i = 0; i <= 3; i++)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = 1 + j;
                while (k < 4)
                {
                    next = map[i][k];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = next;
                        map[i][k] = 0;
                        k = 4;
                    }
                    k++;
                }
            }
        }
    }
    return change;
}

int right()
{
    int now, next, k;
    for (int i = 0; i <= 3; i++)
    {
        for (int j = 3; j >= 0; j--)
        {
            now = map[i][j];
            if (now != 0)
            {
                k = j - 1;
                while (k >= 0)
                {
                    next = map[i][k];
                    if (next != 0)
                    {
                        if (now == next)
                        {
                            change = 1;
                            map[i][j] = 2 * map[i][k];
                            map[i][k] = 0;
                        }
                        k = -1;
                    }
                    k--;
                }
            }
        }
    }

    for (int i = 0; i <= 3; i++)
    {
        for (int j = 3; j >= 0; j--)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = j - 1;
                while (k >= 0)
                {
                    next = map[i][k];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = next;
                        map[i][k] = 0;
                        k = -1;
                    }
                    k--;
                }
            }
        }
    }
    return change;
}

int down()
{
    int now, next, k;
    for (int j = 0; j <= 3; j++)
    {
        for (int i = 0; i <= 3; i++)
        {
            now = map[i][j];
            if (now != 0)
            {
                k = i - 1;
                while (k >= 0)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        if (now == next)
                        {
                            change = 1;
                            map[i][j] = 2 * map[k][j];
                            map[k][j] = 0;
                        }
                        k = -1;
                    }
                    k--;
                }
            }
        }
    }

    for (int j = 0; j <= 3; j++)
    {
        for (int i = 0; i <= 3; i++)
        {
            now = map[i][j];
            if (now == 0)
            {
                k = 1 + i;
                while (k >= 0)
                {
                    next = map[k][j];
                    if (next != 0)
                    {
                        change = 1;
                        map[i][j] = next;
                        map[k][j] = 0;
                        k = -1;
                    }
                    k--;
                }
            }printf("|\n   |---------------------------------------|\n");
        }
    }
    return change;
}

void move()
{
    int i = 0;
    input = getchar();
    change = 0;
    switch (input)
    {
    case'0':
        printf("do you want exit?(y/n)\n");
        input = getchar();
        if (input == 'y' || input == 'Y') exit(0);
        break;
    case'w':
    case'W':
        up();
        break;
    case'a':
    case'A':
        left();
        break;
    case's':
    case'S':
        down();
        break;
    case'd':
    case'D':
        right();
        break;
    }
}

int over()
{
    gameover = 0;
    for (int i = 0; i <= 3; i++)
    {
        for (int j = 0; j <= 3; j++)
        {
            if (map[i][j] == 0) gameover = 1;
            if (i > 1)
            {
                if (map[i][j] == map[i - 1][j]) gameover = 1;
            }
            if (j > 1)
            {
                if (map[i][j] == map[i][j - 1]) gameover = 1;
            }
        }
    }
    return gameover;
}
int main()
{
    srand((unsigned)time(NULL));
    while (gameover == 1)
    {
        randnum();
        menu();
        move();
        over();
    }
    return 0;
}
